package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.mappers.DRouteVehiclePriceEffectiveMapper;
import cn.huiyunche.base.service.mappers.ext.DRouteVehiclePriceEffectiveExtMapper;
import cn.huiyunche.base.service.model.DRouteVehiclePriceEffective;
import cn.huiyunche.base.service.model.DRouteVehiclePriceEffectiveExample;
import cn.huiyunche.base.service.model.DVehiclePreKilometerFeeEffective;
import cn.huiyunche.base.service.vo.DRouteVehiclePriceEffectiveVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.driver.service.DRouteVehiclePriceEffectiveService;
import cn.huiyunche.driver.service.DVehiclePreKilometerFeeEffectiveService;
import cn.huiyunche.driver.service.form.DRouteVehiclePriceEffectiveForm;
import cn.huiyunche.driver.service.query.DRouteVehiclePriceEffectiveQueryConditions;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.math.BigDecimal;
import java.util.*;

/**
 * @FileName: cn.huiyunche.driver.service.impl
 * @Description: Description
 * @author: Aaron
 * @date: 2017/2/26 下午1:27
 */
@Service
public class DRouteVehiclePriceEffectiveServiceImpl implements DRouteVehiclePriceEffectiveService {

    private static final Logger LOGGER = LoggerFactory.getLogger(DRouteVehiclePriceEffectiveServiceImpl.class);

    @Autowired
    private DRouteVehiclePriceEffectiveMapper dRouteVehiclePriceEffectiveMapper;

    @Autowired
    private DRouteVehiclePriceEffectiveExtMapper dRouteVehiclePriceEffectiveExtMapper;

    @Autowired
    private DVehiclePreKilometerFeeEffectiveService dVehiclePreKilometerFeeEffectiveService;

    @Override
    public Integer add(DRouteVehiclePriceEffectiveForm form, BindingResult br) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.add params : {}", form);

        if (null == form) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.add param form must not be null");
            throw new IllegalArgumentException("车型线路价格变动表单不能为空");
        }

        //验证表单
        verificationForm(br);

        /**
         * 只允许存在一条未激活的车型线路变动记录，若已经存在则不能添加
         */
        List<DRouteVehiclePriceEffective> effectives = this.selectNotEffective(form.getRouteId(), form.getVehicleTypeId());
        if (CollectionUtils.isNotEmpty(effectives)) {
            LOGGER.error("DRouteServiceImpl.add error effectives is not empty ");
            throw new BusinessException("已经存在未激活的线路车型价格信息！");
        }

        DRouteVehiclePriceEffective route = new DRouteVehiclePriceEffective();
        BeanUtils.copyProperties(form, route);
        dRouteVehiclePriceEffectiveMapper.insertSelective(route);

        /**
         * 新增线路车型价格信息时更新上一条的失效时间为新增记录的生效时间
         */
        DRouteVehiclePriceEffective currentEffective = this.selectCurrentlyActive();
        if (null != currentEffective) {
            currentEffective.setInvalidDate(form.getEffectiveDate());
            this.update(currentEffective);
        }

        return route.getId();
    }

    @Override
    public Integer update(DRouteVehiclePriceEffectiveForm form, BindingResult br) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.update param : {}", form);

        if (null == form) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("车型线路价格变动表单不能为空");
        }

        //验证表单
        verificationForm(br);

        /**
         * 只允许存在一条未激活的车型线路变动记录，若已经存在则不能添加
         */
        List<DRouteVehiclePriceEffective> effectives = this.selectNotEffective(form.getRouteId(), form.getVehicleTypeId());
        if (CollectionUtils.isNotEmpty(effectives)) {
            DRouteVehiclePriceEffective effective = effectives.get(0);
            if (null != form.getId() && form.getId() != effective.getId()) {
                LOGGER.error("DRouteServiceImpl.update error effectives is not empty ");
                throw new BusinessException("已经存在未激活的线路车型价格变动信息！");
            }
        } else {
            LOGGER.error("DRouteServiceImpl.update error effectives is not empty ");
            throw new BusinessException("修改的线路车型价格变动不可更改！");
        }

        DRouteVehiclePriceEffective route = new DRouteVehiclePriceEffective();
        BeanUtils.copyProperties(form, route);
        dRouteVehiclePriceEffectiveMapper.updateByPrimaryKeySelective(route);

        /**
         * 新增线路车型价格信息时更新上一条的失效时间为新增记录的生效时间
         */
        DRouteVehiclePriceEffective currentEffective = this.selectCurrentlyActive();
        if (null != currentEffective) {
            currentEffective.setInvalidDate(form.getEffectiveDate());
            this.update(currentEffective);
        }

        return route.getId();
    }

    @Override
    public DRouteVehiclePriceEffective selectByPrimaryKey(Integer id) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.selectByPrimaryKeyp param : {}", id);

        if (null == id) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.selectByPrimaryKeyp param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        return dRouteVehiclePriceEffectiveMapper.selectByPrimaryKey(id);
    }

    private void verificationForm(BindingResult br) {

        if (null == br) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.verificationForm error br is null");
            throw new IllegalArgumentException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            LOGGER.error("DRouteServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new IllegalArgumentException(list.get(0).getDefaultMessage());
        }
    }

    @Override
    public void delete(String ids) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.delete param : {}", ids);

        if (StringUtils.isBlank(ids)) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.delete error ids must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }

        String[] split = ids.split(",");
        List<String> strings = Arrays.asList(split);
        List<Integer> id = strings.stream().mapToInt(Integer::parseInt).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

        DRouteVehiclePriceEffectiveExample example = new DRouteVehiclePriceEffectiveExample();
        example.createCriteria().andIdIn(id);

        dRouteVehiclePriceEffectiveMapper.deleteByExample(example);
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, DRouteVehiclePriceEffectiveQueryConditions conditions) {
        LOGGER.info("DRouteServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);

//        if( null == pageVo ){
//            LOGGER.error("DRouteServiceImpl.selectListByConditions param pageVo must not be null");
//            throw new IllegalArgumentException("分页信息不能为空");
//        }
        if (null == conditions) {
            LOGGER.error("DRouteServiceImpl.selectListByConditions param conditions must not be null");
            throw new IllegalArgumentException("查询条件信息不能为空");
        }

        Map<String, Object> map = new HashMap<>();

        String orderByClause = null;
        if (null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder()) == true ? pageVo.getOrder() : " rvp.create_time DESC";
        }

        DRouteVehiclePriceEffectiveExample example = new DRouteVehiclePriceEffectiveExample();
        DRouteVehiclePriceEffectiveExample.Criteria criteria = example.createCriteria();

        if (null != conditions.getRouteId()) {
            criteria.andRouteIdEqualTo(conditions.getRouteId());
        }
        if (null != conditions.getVehicleTypeId()) {
            criteria.andVehicleTypeIdEqualTo(conditions.getVehicleTypeId());
        }
        if (null != conditions.getEffectiveDate()) {
            criteria.andEffectiveDateGreaterThanOrEqualTo(conditions.getEffectiveDate());
        }
        if (null != conditions.getInvalidDate()) {
            criteria.andInvalidDateLessThanOrEqualTo(conditions.getInvalidDate());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(dRouteVehiclePriceEffectiveExtMapper.countByExample(example));
            example.setLimitStart(pageVo.getStartIndex());
            example.setLimitEnd(pageVo.getPageSize());
            example.setOrderByClause(orderByClause);
        }

        List<DRouteVehiclePriceEffectiveVo> list = dRouteVehiclePriceEffectiveExtMapper.selectByExample(example);
        map.put("list", list);

        if (null != pageVo) {
            map.put("page", pageVo);
        }

        return map;
    }

    @Override
    public List<DRouteVehiclePriceEffective> selectNotEffective(Integer routeId, Integer vehicleTypeId) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.selectNotEffective invoking ");

        if (null == routeId) {
            LOGGER.info("DRouteVehiclePriveEffectiveServiceImpl.selectNotEffective routeId must be not null");
            throw new IllegalArgumentException("线路ID不能为空");
        } else if (null == vehicleTypeId) {
            LOGGER.info("DRouteVehiclePriveEffectiveServiceImpl.selectNotEffective vehicleTypeId must be not null");
            throw new IllegalArgumentException("车辆类型ID不能为空");
        }

        DRouteVehiclePriceEffectiveExample example = new DRouteVehiclePriceEffectiveExample();
        example.createCriteria().andRouteIdEqualTo(routeId).andVehicleTypeIdEqualTo(vehicleTypeId)
                .andEffectiveDateGreaterThan(new Date()).andInvalidDateIsNull();

        return dRouteVehiclePriceEffectiveMapper.selectByExample(example);
    }

    @Override
    public DRouteVehiclePriceEffective selectCurrentlyActive() {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.selectCurrentlyActive invoking ");

        DRouteVehiclePriceEffectiveExample example = new DRouteVehiclePriceEffectiveExample();
        example.createCriteria().andEffectiveDateLessThanOrEqualTo(new Date()).andInvalidDateIsNull();

        List<DRouteVehiclePriceEffective> dRouteVehiclePriceEffectives = dRouteVehiclePriceEffectiveMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(dRouteVehiclePriceEffectives)) {
            return dRouteVehiclePriceEffectives.get(0);
        }

        return null;
    }

    @Override
    public void update(DRouteVehiclePriceEffective effective) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.update params : {}", effective);

        if (null == effective) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.update param effective must not be null");
            throw new IllegalArgumentException("车型线路价格变动信息不能为空");
        }

        dRouteVehiclePriceEffectiveMapper.updateByPrimaryKeySelective(effective);
    }

    @Override
    public BigDecimal calcTotalPrice(Integer vehicleTypeId, BigDecimal labourServicesPrice, Date effectiveDate) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.calcTotalPrice param : {}", vehicleTypeId);

        if (null == vehicleTypeId || 0 == vehicleTypeId.intValue()) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.calcTotalPrice param vehicleTypeId must not be null");
            throw new IllegalArgumentException("车型主键不能为空");
        }

        if (null == labourServicesPrice) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.calcTotalPrice param labourServicesPrice must not be null");
            throw new IllegalArgumentException("劳务费不能为空");
        }

        if (null == effectiveDate) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.calcTotalPrice param effectiveDate must not be null");
            throw new IllegalArgumentException("车型每公里油费变动激活时间不能为空");
        }

        DVehiclePreKilometerFeeEffective vehiclePreKilometerFeeEffective = dVehiclePreKilometerFeeEffectiveService.selectActivedByEffectiveDate(vehicleTypeId, effectiveDate);
        if (null == vehiclePreKilometerFeeEffective) {
            LOGGER.error("DRouteVehiclePriceEffectiveServiceImpl.calcTotalPrice vehiclePreKilometerFeeEffective must not be null");
            throw new BusinessException("车型每公里油费变动不能为空");
        }

        return vehiclePreKilometerFeeEffective.getPerKmOilFee() != null ?
                vehiclePreKilometerFeeEffective.getPerKmOilFee().add(labourServicesPrice) : labourServicesPrice;
    }

    @Override
    public DRouteVehiclePriceEffective getById(Integer id) {
        LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.getById param id: {}", id);
        if (null == id) {
            LOGGER.info("DRouteVehiclePriceEffectiveServiceImpl.getById id must not be null");
            throw new BusinessException("主键不能为空");
        }
        return this.dRouteVehiclePriceEffectiveMapper.selectByPrimaryKey(id);
    }
}
